home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir27 / calctool.zip / X11.ORG < prev    next >
Text File  |  1992-09-10  |  15KB  |  537 lines

  1.  
  2. /*  @(#)x11.c 1.14 89/12/21
  3.  *
  4.  *  These are the X11 dependent graphics routines used by calctool.
  5.  *
  6.  *  Copyright (c) Rich Burridge.
  7.  *                Sun Microsystems, Australia - All rights reserved.
  8.  *
  9.  *  Permission is given to distribute these sources, as long as the
  10.  *  copyright messages are not removed, and no monies are exchanged.
  11.  *
  12.  *  No responsibility is taken for any errors or inaccuracies inherent
  13.  *  either to the comments or the code of this program, but if
  14.  *  reported to me then an attempt will be made to fix them.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include "calctool.h"
  19. #include "color.h"
  20. #include "extern.h"
  21. #include <X11/Xlib.h>
  22. #include <X11/Xutil.h>
  23. #include <X11/Xatom.h>
  24. #include <X11/cursorfont.h>
  25. #include <X11/keysym.h>
  26.  
  27. #define  XGETSIZEHINTS  (void) XGetSizeHints
  28.  
  29. #define  BIGFONT               "helvetica-bold-14"
  30. #define  DEFFONT               "fixed"
  31. #define  NORMALFONT            "fixed"
  32. #define  SMALLFONT             "6x10"
  33.  
  34. #define  CALCTOOL_BORDER_WIDTH  2
  35.  
  36. #define  FRAME_MASK  (ButtonPressMask | ButtonReleaseMask | KeyPressMask | \
  37.                       EnterWindowMask | LeaveWindowMask | ExposureMask)
  38.  
  39. short help_cursor_array[16] = {
  40. #include "help.cursor"
  41. } ;
  42.  
  43. short icon_image[] = {
  44. #include "calctool.icon"
  45. } ;
  46.  
  47. short cicon_image[] = {
  48. #include "calctool.ico"
  49. } ;
  50.  
  51. Atom protocol_atom, kill_atom ;
  52. Cursor help_cursor, main_cursor ;
  53. Display *dpy ;
  54. GC gc ;
  55. Pixmap calctool_icon, help_pixmap ;
  56. Pixmap load_icon() ;
  57. Window frame, rframe ;
  58. XColor BGcolor, FGcolor, current_col ;
  59. XEvent event ;
  60. XFontStruct *bfont, *font, *nfont, *sfont ;
  61. XGCValues gc_val ;
  62. XSizeHints size ;
  63. XWMHints wm_hints ;
  64.  
  65. unsigned long gc_mask ;
  66. int screen ;
  67. unsigned int scr_depth ;
  68. unsigned long backgnd, foregnd ;
  69. unsigned long palette[CALC_COLORSIZE] ;
  70.  
  71.  
  72. clear_canvas(ctype, color)
  73. enum can_type ctype ;
  74. int color ;
  75. {
  76.   int x, y ;
  77.   unsigned int width, height, bwidth, depth ;
  78.   Window root, window ;
  79.  
  80.        if (ctype == KEYCANVAS) window = frame ;
  81.   else if (ctype == REGCANVAS) window = rframe ;
  82.   XGetGeometry(dpy, window, &root, &x, &y, &width, &height, &bwidth, &depth) ;
  83.   if (iscolor) gc_val.foreground = palette[color] ;
  84.   else
  85.     {
  86.       if (color == WHITE) gc_val.foreground = backgnd ;
  87.       else gc_val.foreground = foregnd ;
  88.     }
  89.   gc_val.function = GXcopy ;
  90.   XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
  91.   XFillRectangle(dpy, window, gc, x, y, width, height) ;
  92. }
  93.  
  94.  
  95. close_frame()
  96. {
  97.   XEvent event ;
  98.  
  99.   event.xclient.type = ClientMessage ;
  100.   event.xclient.display = dpy ;
  101.   event.xclient.window = frame ;
  102.   event.xclient.message_type = XInternAtom(dpy, "WM_CHANGE_STATE", False) ;
  103.   event.xclient.format = 32 ;
  104.   event.xclient.data.l[0] = IconicState ;
  105.   XSendEvent(dpy, DefaultRootWindow(dpy), False,
  106.           SubstructureRedirectMask | SubstructureNotifyMask, &event) ;
  107.   XFlush(dpy) ;
  108. }
  109.  
  110.  
  111. color_area(x, y, width, height, color)
  112. int x, y, width, height, color ;
  113. {
  114.   if (iscolor) gc_val.foreground = palette[color] ;
  115.   else
  116.     {
  117.       if (color == WHITE) gc_val.foreground = backgnd ;
  118.       else gc_val.foreground = foregnd ;
  119.     }
  120.   gc_val.function = GXcopy ;
  121.   XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
  122.   XFillRectangle(dpy, frame, gc, x, y,
  123.                  (unsigned int) width, (unsigned int) height) ;
  124. }
  125.  
  126.  
  127. create_menu(mtype)    /* Create popup menu for right button press. */
  128. enum menu_type mtype ;
  129. {
  130. }
  131.  
  132.  
  133. destroy_frame()
  134. {
  135.   XDestroyWindow(dpy, frame) ;
  136.   XDestroyWindow(dpy, rframe) ;
  137.   exit(0) ;
  138. }
  139.  
  140.  
  141. do_menu(mtype)      /* Popup appropriate menu and get value. */
  142. enum menu_type mtype ;
  143. {
  144. }
  145.  
  146.  
  147. drawline(x1, y1, x2, y2)
  148. int x1, y1, x2, y2 ;
  149. {
  150.   if (iscolor) gc_val.foreground = palette[BLACK] ;
  151.   else gc_val.foreground = foregnd ;
  152.   gc_val.function = GXcopy ;
  153.   XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
  154.   XDrawLine(dpy, frame, gc, x1, y1, x2, y2) ;
  155. }
  156.  
  157.  
  158. draw_regs()
  159. {
  160.   XMapWindow(dpy, rframe) ;
  161. }
  162.  
  163.  
  164. drawtext(x, y, ctype, fontno, color, str)
  165. enum font_type fontno ;
  166. enum can_type ctype ;
  167. int x, y, color ;
  168. char *str ;
  169. {
  170.   Window window ;
  171.  
  172.        if (fontno == SFONT) font = sfont ;
  173.   else if (fontno == NFONT) font = nfont ;
  174.   else if (fontno == BFONT) font = bfont ;
  175.        if (ctype == KEYCANVAS) window = frame ;
  176.   else if (ctype == REGCANVAS) window = rframe ;
  177.  
  178.   if (ctype == KEYCANVAS && y == items[(int) DISPLAYITEM].y) x += 100 ;
  179.   if (iscolor) gc_val.foreground = palette[color] ;
  180.   else
  181.     {
  182.       if (color == WHITE) gc_val.foreground = backgnd ;
  183.       else gc_val.foreground = foregnd ;
  184.     }
  185.   gc_val.font = font->fid ;
  186.   gc_val.function = GXcopy ;
  187.   XChangeGC(dpy, gc, GCFont | GCForeground | GCFunction, &gc_val) ;
  188.   XDrawString(dpy, window, gc, x, y, str, strlen(str)) ;
  189. }
  190.  
  191.  
  192. get_display()         /* GET function key was pressed. */
  193. {
  194. }
  195.  
  196.  
  197. XFontStruct *
  198. get_font(name)
  199. char *name ;
  200. {
  201.   XFontStruct *font ;
  202.  
  203.   if (!(font = XLoadQueryFont(dpy, name)))
  204.     if (!(font = XLoadQueryFont(dpy, DEFFONT)))
  205.       {
  206.         perror("couldn't get the default font.") ;
  207.         exit(1) ;
  208.       }
  209.   return(font) ;
  210. }
  211.  
  212.  
  213. get_next_event()
  214. {
  215.   XClientMessageEvent *ev ;
  216.   XKeyPressedEvent *key_event ;
  217.   KeySym keysym ;
  218.   char chs[2] ;
  219.  
  220.   if (!XCheckMaskEvent(dpy, ExposureMask, &event))
  221.     XNextEvent(dpy, &event) ;
  222.  
  223.   switch (event.type)
  224.     {
  225.       case ClientMessage    : /* Catch ICCCM kill from WM. */
  226.  
  227.                               ev = (XClientMessageEvent *) &event ;
  228.                               if (ev->message_type == protocol_atom &&
  229.                                   ev->data.l[0] == kill_atom)
  230.                                 exit(0) ;
  231.                               return(LASTEVENTPLUSONE) ;
  232.  
  233.       case Expose           : return(process_expose(&event)) ;
  234.  
  235.       case EnterNotify      : return(ENTER_WINDOW) ;
  236.  
  237.       case LeaveNotify      : return(EXIT_WINDOW) ;
  238.  
  239.       case KeyPress         : key_event = (XKeyPressedEvent *) &event ;
  240.                               curx = key_event->x ;
  241.                               cury = key_event->y ;
  242.                               (void) XLookupString(key_event, chs, 1,
  243.                                                    &keysym,
  244.                                                    (XComposeStatus *) NULL) ;
  245.                               if (keysym == XK_Shift_L ||
  246.                                   keysym == XK_Shift_R) break ;
  247.                               cur_ch = chs[0] ;
  248.                               return(KEYBOARD) ;
  249.  
  250.       case ButtonPress      : curx = event.xbutton.x ;
  251.                               cury = event.xbutton.y ;
  252.                               if (event.xbutton.button == Button1)
  253.                                 return(LEFT_DOWN) ;
  254.                               else if (event.xbutton.button == Button2)
  255.                                 return(MIDDLE_DOWN) ;
  256.                               else if (event.xbutton.button == Button3)
  257.                                 return(RIGHT_DOWN) ;
  258.  
  259.       case ButtonRelease    : curx = event.xbutton.x ;
  260.                               cury = event.xbutton.y ;
  261.                               if (event.xbutton.button == Button1)
  262.                                 return(LEFT_UP) ;
  263.                               else if (event.xbutton.button == Button2)
  264.                                 return(MIDDLE_UP) ;
  265.                               else if (event.xbutton.button == Button3)
  266.                                 return(RIGHT_UP) ;
  267.  
  268.       default               : return(LASTEVENTPLUSONE) ;
  269.    }
  270. /*NOTREACHED*/
  271. }
  272.  
  273.  
  274. handle_selection()
  275. {
  276. }
  277.  
  278.  
  279. init_fonts()
  280. {
  281.   bfont = get_font(BIGFONT) ;
  282.   nfont = get_font(NORMALFONT) ;
  283.   nfont_width = 6 ;
  284.   sfont = get_font(SMALLFONT) ;
  285. }
  286.  
  287.  
  288. init_ws_type()
  289. {
  290.   if ((dpy = XOpenDisplay(x11_display)) == NULL)
  291.     {
  292.       FPRINTF(stderr,"%s: Couldn't open display %s\n", progname,
  293.               (getenv ("DISPLAY") ? getenv("DISPLAY") : x11_display)) ;
  294.       exit(1) ;
  295.     }
  296.  
  297.   screen = DefaultScreen(dpy) ;
  298.  
  299.   if (*geometry == '\0')
  300.     STRCPY(geometry, XGetDefault(dpy, progname, "Geometry")) ;
  301.  
  302.   foregnd = BlackPixel(dpy, screen) ;
  303.   backgnd = WhitePixel(dpy, screen) ;
  304.   scr_depth = DefaultDepth(dpy, screen) ;
  305.   gtype = X11 ;
  306.   return 0 ;
  307. }
  308.  
  309.  
  310. load_colors()      /* Create and load calctool color map. */
  311. {
  312.   u_char red[CALC_COLORSIZE], green[CALC_COLORSIZE], blue[CALC_COLORSIZE] ;
  313.   int i, numcolors ;
  314.  
  315.   iscolor = 0 ;
  316.   if (DisplayCells(dpy, screen) > 2)
  317.     {
  318.       calc_colorsetup(red, green, blue) ;
  319.       iscolor = 1 ;
  320.       numcolors = 0 ;
  321.       for (i = 0; i < CALC_COLORSIZE; i++)
  322.         {
  323.           current_col.flags = DoRed | DoGreen | DoBlue ;
  324.           current_col.red = (unsigned short) (red[i] << 8) ;
  325.           current_col.green = (unsigned short) (green[i] << 8) ;
  326.           current_col.blue = (unsigned short) (blue[i] << 8) ;
  327.           if (XAllocColor(dpy, DefaultColormap(dpy, screen), ¤t_col) == True)
  328.             palette[numcolors++] = current_col.pixel ;
  329.         }
  330.       if (numcolors < 2)
  331.         {
  332.           FPRINTF(stderr, "%s: cannot allocate colors.\n", progname) ;
  333.           exit(1) ;
  334.         }
  335.     }
  336. }
  337.  
  338.  
  339. Cursor
  340. load_cursor(sbuf)
  341. short sbuf[16] ;
  342. {
  343.   char cbuf[32] ;
  344.   int i ;
  345.  
  346.   for (i = 0; i < 16; i++)
  347.     {
  348.       cbuf[i*2+0] = revtable[(sbuf[i] >> 8) & 0xFF] ;
  349.       cbuf[i*2+1] = revtable[sbuf[i] & 0xFF] ;
  350.     }
  351.   help_pixmap = XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, screen), cbuf,
  352.                                      16, 16, foregnd, backgnd, 1) ;
  353.   return(XCreatePixmapCursor(dpy, help_pixmap, help_pixmap,
  354.                                     &FGcolor, &BGcolor, 0, 0)) ;
  355. }
  356.  
  357.  
  358. Pixmap
  359. load_icon(sbuf)
  360. short sbuf[] ;
  361. {
  362.   GC pix_gc ;
  363.   Pixmap pixmap ;
  364.   XImage *image ;
  365.   char cbuf[512*8] ;
  366.   int i ;
  367.  
  368.   if (iscolor)
  369.     {
  370.       for (i = 0; i < (256*8); i++)
  371.         {
  372.           cbuf[i*2+0] = palette[(sbuf[i] >> 8) & 0xFF] ;
  373.           cbuf[i*2+1] = palette[sbuf[i] & 0xFF] ;
  374.         }
  375.       pix_gc = DefaultGC(dpy, screen) ;
  376.       image = XCreateImage(dpy, DefaultVisual(dpy, screen),
  377.                            scr_depth, ZPixmap, 0, cbuf, 64, 64, 8, 64) ;
  378.       pixmap = XCreatePixmap(dpy, RootWindow(dpy, screen),
  379.                              ICONWIDTH, (unsigned) image->height, scr_depth) ;
  380.       XPutImage(dpy, pixmap, pix_gc, image, 0, 0, 0, 0,
  381.                 ICONWIDTH, (unsigned) image->height) ;
  382.     }
  383.   else
  384.     {
  385.       for (i = 0; i < 256; i++)
  386.         {
  387.           cbuf[i*2+0] = revtable[(sbuf[i] >> 8) & 0xFF] ;
  388.           cbuf[i*2+1] = revtable[sbuf[i] & 0xFF] ;
  389.         }
  390.       pixmap = XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, screen), cbuf,
  391.                                      64, 64, foregnd, backgnd, scr_depth) ;
  392.     }
  393.   return(pixmap) ;
  394. }
  395.  
  396.  
  397. make_frames(argc, argv)
  398. int argc ;
  399. char *argv[] ;
  400. {
  401.   unsigned int h, w ;       /* Window dimensions. */
  402.   int flags ;
  403.   int x, y ;                /* Window position. */
  404.            
  405.   load_colors() ;
  406.   if (iscolor) calctool_icon = load_icon(cicon_image) ;
  407.   else calctool_icon = load_icon(icon_image) ;
  408.  
  409.   size.flags = PMinSize | PMaxSize | PPosition | PSize ;
  410.   size.x = 0 ;
  411.   size.y = 0 ;
  412.   size.max_width = size.min_width = size.width = TWIDTH ;
  413.   size.max_height = size.min_height = size.height = THEIGHT + DISPLAY ;
  414.  
  415.   if (strlen(geometry))
  416.     {
  417.       flags = XParseGeometry(geometry, &x, &y, &w, &h) ;
  418.       if (XValue & flags)
  419.         {
  420.           if (XNegative & flags)
  421.             x = DisplayWidth(dpy, screen) + x - size.width ;
  422.             size.flags |= USPosition ;
  423.             size.x = x ;
  424.         }
  425.       if (YValue & flags)
  426.         {
  427.           if (YNegative & flags)
  428.             y = DisplayHeight(dpy, screen) + y - size.height ;
  429.             size.flags |= USPosition ;
  430.             size.y = y ;
  431.         }      
  432.     }
  433.  
  434.   frame = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
  435.                               size.x, size.y, size.width, size.height,
  436.                               CALCTOOL_BORDER_WIDTH, foregnd, backgnd) ;
  437.  
  438.   rframe = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
  439.                                size.x + TWIDTH + 15, size.y,
  440.                                size.width, 200,
  441.                                CALCTOOL_BORDER_WIDTH, foregnd, backgnd) ;
  442.  
  443.   protocol_atom = XInternAtom(dpy, "WM_PROTOCOLS", False) ;
  444.   kill_atom = XInternAtom(dpy, "WM_DELETE_WINDOW", False) ;
  445.  
  446.   XSetStandardProperties(dpy, frame, "calctool", NULL, calctool_icon,
  447.                          argv, argc, &size) ;
  448.  
  449.   wm_hints.icon_x = ix ;
  450.   wm_hints.icon_y = iy ;
  451.   wm_hints.input = True ;
  452.   wm_hints.icon_pixmap = calctool_icon ;
  453.   wm_hints.flags = InputHint | IconPixmapHint ;
  454.   if (iconic)
  455.     {
  456.       wm_hints.initial_state = IconicState ;
  457.       wm_hints.flags |= StateHint ;
  458.     }
  459.   XSetWMHints(dpy, frame, &wm_hints) ;
  460.  
  461.   gc_mask = GCFont | GCForeground | GCBackground | GCGraphicsExposures ;
  462.   gc_val.font = nfont->fid ;
  463.   gc_val.foreground = foregnd ;
  464.   gc_val.background = backgnd ;
  465.   gc_val.graphics_exposures = False ;
  466.   gc = XCreateGC(dpy, RootWindow(dpy, screen), gc_mask, &gc_val) ;
  467.   XSetFunction(dpy, gc, GXcopy) ;
  468.  
  469.   main_cursor = XCreateFontCursor(dpy, XC_top_left_arrow) ;
  470.   FGcolor.red = FGcolor.green = FGcolor.blue = 0 ;
  471.   BGcolor.red = BGcolor.green = BGcolor.blue = 0xffff ;
  472.   help_cursor = load_cursor(help_cursor_array) ;
  473. }
  474.  
  475.  
  476. make_icon() {}        /* Null routine - icon created in make_frame. */
  477.  
  478.  
  479. make_items()
  480. {
  481.   XSelectInput(dpy, frame, FRAME_MASK) ;
  482.   XMapWindow(dpy, frame) ;
  483.  
  484.   XSelectInput(dpy, rframe, ExposureMask) ;
  485. }
  486.  
  487.  
  488. make_subframes() {}          /* Null routine, see the make_frame routine. */
  489.  
  490.  
  491. process_expose(event)
  492. XExposeEvent *event ;
  493. {
  494.   int doframe, dorframe ;
  495.  
  496.   doframe = dorframe = 0 ;
  497.   do
  498.     {
  499.       if (event->count == 0)
  500.         {
  501.                if (event->window == frame) doframe++ ;
  502.           else if (event->window == rframe) dorframe++ ;
  503.         }
  504.     }
  505.   while (XCheckMaskEvent(dpy, ExposureMask, event)) ;
  506.  
  507.   if (dorframe && rstate) make_registers() ;
  508.   if (doframe) return(CFRAME_REPAINT) ;
  509. }
  510.  
  511.  
  512. set_cursor(type)
  513. int type ;
  514. {
  515.   switch (type)
  516.     {
  517.       case HELPCURSOR : XDefineCursor(dpy, frame, help_cursor) ;
  518.                         break ;
  519.       case MAINCURSOR : XDefineCursor(dpy, frame, main_cursor) ;
  520.     }
  521. }
  522.  
  523.  
  524. start_tool()
  525. {
  526.   while (1)
  527.     process_event(get_next_event()) ;
  528. }
  529.  
  530.  
  531. toggle_reg_canvas()
  532. {
  533.   rstate = !rstate ;
  534.   if (rstate) XMapWindow(dpy, rframe) ;
  535.   else XUnmapWindow(dpy, rframe) ;
  536. }
  537.